package client

import (
	"bufio"
	"context"
	"fmt"
	"github.com/patrickmn/go-cache"
	"net"
	"os"
	"protocol/common"
	"strings"
	"time"
)

// 定义全局变量
var goCahce *cache.Cache

func Init() {
	if goCahce == nil {
		goCahce = cache.New(5*time.Minute, 60*time.Second)
	}
}

func Connect(host string, port int) {
	address := fmt.Sprintf("%s:%d", host, port)
	ctx := context.TODO()
	//dialer := net.Dialer{
	//	Timeout:   5000,
	//	KeepAlive: 30 * time.Second,
	//}
	ctx.Value("yymagicer")
	//conn, err := dialer.DialContext(ctx, "tcp", address)
	conn, err := net.DialTimeout("tcp", address, time.Second*5)
	if err != nil {
		fmt.Printf("dial failed, err: %v\n", err)
		return
	}

	fmt.Println("conn established...")
	//初始化缓存
	Init()

	go func() {
		fmt.Println("establish listner")
		//建立监听
		listener(conn)
	}()

	//处理控制台输入
	reader := bufio.NewReader(os.Stdin)
	for {
		data, err := reader.ReadString('\n')
		if err != nil {
			fmt.Printf("read from console failed, err:%v\n", err)
			break
		}
		err = SendMessage(data, conn)
		if err != nil {
			fmt.Printf("write failed, err:%v\n", err)
			break
		}
	}
}

// 心跳连接
func heartbeat(conn net.Conn) {
	conectMessage, ok := goCahce.Get(conn.RemoteAddr().String())
	if ok {
		connectMessage := conectMessage.(common.ConnectMessage)
		fmt.Printf(" %s send heartbeat \n", connectMessage.Name)
		receiverMessage := common.HeartbeatMessage{Value: "health", ConnectMessage: connectMessage}
		conn.Write(common.BuildMessageForType(common.HEARTBEAT, nil, receiverMessage))
	} else {
		fmt.Printf("not found :%s conn cache", conn.RemoteAddr().String())
		return
	}
}

// SendMessage 发送消息
func SendMessage(content string, conn net.Conn) error {
	message := common.ParseBytes[common.Message]([]byte(content))
	if message.MessageType == common.ESTABLISH_CONNECTION {
		connectMessage := common.ParseString[common.ConnectMessage](message.Body)
		//设置缓存
		goCahce.Set(conn.RemoteAddr().String(), connectMessage, -1*time.Minute)
		go func() {
			for {
				time.Sleep(5 * time.Second)
				//五秒钟 发送心跳一次
				heartbeat(conn)
			}

		}()
	}
	if conn != nil {
		_, err := conn.Write([]byte(strings.TrimSpace(content)))
		if err != nil {
			fmt.Printf("send message failed, err:%v\n", err)
			return err
		}
		fmt.Printf("send message :%v \n", content)
		return nil
	}
	return nil
}

// Listener 建立消息监听
func listener(conn net.Conn) {
	if conn != nil {
		for {
			var buf [128]byte
			n, err := conn.Read(buf[:])
			if err != nil {
				fmt.Printf("read from conn failed, err: %v", err)
				break
			}
			fmt.Printf("recv from Server, content: %v\n", string(buf[:n]))
		}
	}
}
